package net.yakiboo.adrums;


import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import net.yakiboo.util.ClientServer;
import net.yakiboo.util.FileManager;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;

public class Adrums extends Activity implements SensorEventListener {

	private SensorManager mSensorManager;
	private float mOrientationValues[] = new float[3];
	public static double timeUD = 0.050;
	private double time = 0;
	private double lasttime = 0;
	private Paint paint = null;
	private DrawView drumsView = null;
	private double timeInit = 0;
	private float lastVerticalAngle = 0;
	private float drumsStart = 0;
	Drum nearest = null;
	DrumKit drums = null;
	
	private Song cancion=null;
	
	private ToggleButton recButton=null;
	private TextView txtIP=null;
	private ClientServer cs=null;

	
	private Handler handler = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// Be sure to call the super class.
		super.onCreate(savedInstanceState);
		cancion=new Song();
		handler=new Handler();
		drums = DrumKit.genDrumKitExample(this.getApplicationContext());
		
		mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		
		paint = new Paint();
		paint.setDither(true);
		paint.setColor(0xFFFFFF00);
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeJoin(Paint.Join.ROUND);
		paint.setStrokeCap(Paint.Cap.ROUND);
		paint.setStrokeWidth(3);

		setContentView(R.layout.main);
		
		drumsView = (DrawView) findViewById(R.id.drumsView);
		drumsView.setDrumKit(drums);
		drumsView.postInvalidate();
		
		txtIP = (TextView)findViewById(R.id.txtIP);
		recButton = (ToggleButton)findViewById(R.id.recButton);
		
		//recButton.setOnClickListener(recButtonOnClickListener);
		recButton.setOnCheckedChangeListener(recButtonOnCheckedChangeListener);
		new Thread() {			

			public void run() {
				while (true) {
					try {
						if (timeInit == 0) timeInit = time;
						time += timeUD;
						Thread.sleep((int) (timeUD * 1000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
	}
	
	// cambiar a vigilar el start y el stop
	public void surveillance(){
    	Runnable runnable = new Runnable(){
    		boolean record=false;
    		boolean start=false;
    		boolean stop=false;
			@Override
			public void run() {
				while(cs!=null){
					try{
						espera(100);
						record=cs.isRecording();
						start=cs.getStart();
						stop=cs.getStop();
							
					}catch(NullPointerException npe){
						npe.printStackTrace();
					}catch(Exception e){
						e.printStackTrace();
					}
				
					handler.post(new Runnable(){
						@Override
						public void run() {
							recButton.setChecked(record);
							if(stop)
								recButton.setChecked(false);
							else if(start)
								recButton.setChecked(true);
							
						}
					});
				}
				handler.post(new Runnable(){
					@Override
					public void run() {
						recButton.setChecked(false);						
					}
				});
			}
    	};
    	new Thread(runnable).start();
    }
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent){
		super.onActivityResult(requestCode, resultCode, intent);
		
		Bundle bundle = intent.getExtras();
		if (bundle!=null){
			switch(requestCode){
			case 0:
				String IP=bundle.getString("ip");
				boolean isServer=bundle.getBoolean("isServer");
				if(IP.equals("")){
					if(cs!=null)
						cs.onStop();
					cs=null;
					//recButton.setText("REC");
					txtIP.setText("");
				}else{
					if(cs!=null)
						cs.onStop();
					cs=new ClientServer();
					cs.setIsServer(isServer);
					cs.setIP(IP);
					surveillance();
					if(isServer){
						cs.serverJob();
						txtIP.setText("Dirección: " + cs.getIP());
					}else{
						cs.clientJob(IP);
						txtIP.setText("Conectado a: " + cs.getIP());
					}
					//recButton.setText("REC:"+IP);
				}
				break;
			}
		}else{
			cs=null;
		}
	}
	
	private void espera(long time){
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	ToggleButton.OnCheckedChangeListener recButtonOnCheckedChangeListener = new ToggleButton.OnCheckedChangeListener(){
		@Override
		public void onCheckedChanged(CompoundButton buttonView,	boolean isChecked) {
			
			if(!isChecked){
				if(cs!=null){
					cs.setSong(cancion);
					 cs.setStop(true);
					 //TODO: Hacer una espera correcta no aleatoria.
					 espera(100);
					 cancion=cs.getSong();
				}
				 //TODO: Dar a elegir el nombre para almacenar.
				 FileManager.guardar("pruebaClase", cancion);
		        
			 }else
				 if(cs!=null)
					 cs.setStart(true);
		}
    };
    
    /*
	ToggleButton.OnClickListener recButtonOnClickListener = new ToggleButton.OnClickListener(){
		@Override
		public void onClick(View v) {
			 if(!recButton.isChecked()){
				 if(cs!=null)
					 cs.setStop(true);
				 FileManager.guardar("pruebaClase", cancion);
		        
			 }else
				 if(cs!=null)
					 cs.setStart(true);
			 
		}
    };
	*/
    
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    //Alternativa 1
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.mainmenu, menu);
	    return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Bundle bundle;
		Intent intent;
		recButton.setChecked(false);
	    switch (item.getItemId()) {
	        case R.id.menuLoad:
	        	intent = new Intent(Adrums.this, DrumsPlayer.class);
		       	
    	        bundle = new Bundle();
    	        bundle.putBoolean("Loader", true);
    	        intent.putExtras(bundle);
    	 
    	        startActivity(intent);
	            return true;
	        case R.id.menuPlay:
	        	intent = new Intent(Adrums.this, DrumsPlayer.class);
	        	String contenido="";
		       	if(cancion!=null){
		    		for(int i=0; i<cancion.getSound().size();i++)
		    			contenido+=cancion.getSound().get(i) + " ";
		    		contenido+="\n";
		    		for(int i=0; i<cancion.getTime().size();i++)
		    			contenido+=cancion.getTime().get(i) + " ";
		       	}
    	        bundle = new Bundle();
    	        bundle.putBoolean("Loader", false);
    	        bundle.putString("Song", contenido);
    	        
    	        intent.putExtras(bundle);
    	 
    	        startActivity(intent);
	            return true;
	        case R.id.menuConnect:
	        	if(cs!=null)
	        		cs.onStop();
	        	cs=null;
	        	intent = new Intent(Adrums.this, DrumsConnection.class);
	        	startActivityForResult(intent,0);
	        	return true;
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		mSensorManager.registerListener(this,
				mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
				SensorManager.SENSOR_DELAY_FASTEST);
		mSensorManager.registerListener(this,
				mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
				SensorManager.SENSOR_DELAY_FASTEST);
		mSensorManager.registerListener(this,
				mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
				SensorManager.SENSOR_DELAY_FASTEST);
	}

	@Override
	protected void onStop() {
		mSensorManager.unregisterListener(this);
		super.onStop();
		if(cs!=null)
			cs.onStop();
		cs=null;
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	@Override
	public void onSensorChanged(SensorEvent event) {		
		synchronized (this) {

			/* A partir de aqui es para la interfaz */

			if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
				for (int i = 0; i < 3; i++) {
					mOrientationValues[i] = event.values[i];
				}

			}

			if (drumsStart == 0) {
				drumsStart = mOrientationValues[0];
			}

			if (lasttime != time) {

				Log.i("adrums", "mOr[0]=" + mOrientationValues[0] + ", mOr[1]="
						+ mOrientationValues[1] + ", mOri[2]="
						+ mOrientationValues[2]);

				drumsView.setPointer(mOrientationValues[0] - drumsStart + 50);

				float currentVerticalAngle = mOrientationValues[1];
				float diffAngle = currentVerticalAngle - lastVerticalAngle;
				
				Drum prediction = drums
						.getNearestDrum(mOrientationValues[0]
								- drumsStart);
				if (drums != null) {
					for (Drum d : drums.getDrums()) {										
						d.isSelected = false;
					}
					if(prediction != null)
					prediction.isSelected = true;
				}

				if (currentVerticalAngle > lastVerticalAngle && diffAngle > 50) {
					// Sabemos que se da un golpe, ahora vemos donde

					new Thread() {
						@Override
						public void run() {
							try {
								Thread.sleep(200);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							Drum aux = drums
									.getNearestDrum(mOrientationValues[0]
											- drumsStart);
							
							if (aux != null) {
								aux.play();
								if(recButton.isChecked())
									cancion.addSound(aux, time - timeInit);
							}
						}
					}.start();
 
				}

				lastVerticalAngle = currentVerticalAngle;
				lasttime = time; // IMPORTANTE!!!
			}

		}
	}
}